#pragma once

#include "rpc/RPCSession.h"
#include "data/GameServerData.h"

class GameServerSessionHandler;

class GameServerSession : public RPCSession
{
public:
	GameServerSession(const std::string& host,
		const std::string& port, uint32 service, size_t index);
	virtual ~GameServerSession();

	void CheckConnection();

	virtual int HandlePacket(INetPacket *pck);
	virtual void OnConnected();
	virtual void OnShutdownSession();
	virtual void DeleteObject();

	void SendPacket2SS(const INetPacket& pck);
	void SendPacket2SS4Player(
		const std::string_view& info, const INetPacket& pck);

	void RPCInvoke2SS(const INetPacket &pck,
		const std::function<void(INetStream&, int32, bool)> &cb = nullptr,
		AsyncTaskOwner *owner = nullptr, time_t timeout = DEF_RPC_TIMEOUT);
	void RPCReply2SS(const INetPacket &pck,
		uint64 sn, int32 err = RPCErrorNone, bool eof = true);

	const std::string& host() const { return m_host; }
	const std::string& port() const { return m_port; }
	const uint32 service() const { return m_service; }
	const size_t index() const { return m_index; }

	const uint32 serverId() const { return m_serverId; }
	const uint32 sn() const { return m_sn; }

	GameServerData& getVData() { return m_data; }
	const GameServerData& getCData() const { return m_data; }

private:
	virtual void OnRecvPacket(INetPacket *pck);

	void TransInstancePacket(INetPacket *pck) const;
	void TransPlayerPacket(INetPacket *pck) const;
	void TransCrossServerPacket(INetPacket* pck) const;

	friend GameServerSessionHandler;
	const std::string m_host;
	const std::string m_port;
	const uint32 m_service;
	const size_t m_index;

	uint32 m_serverId;
	uint32 m_serviceId;
	uint32 m_sn;

	GameServerData m_data;
};
